package cn.iocoder.yudao.module.system.controller.admin.erp.erpuser;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.exception.ErrorCode;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.module.system.controller.admin.erp.customermanage.vo.CustomerManageSaveReqVO;
import cn.iocoder.yudao.module.system.controller.admin.erp.erpuser.vo.ErpUserPageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.erp.erpuser.vo.ErpUserReqVO;
import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.*;
import cn.iocoder.yudao.module.system.convert.user.UserConvert;
import cn.iocoder.yudao.module.system.core.ErpOperationField;
import cn.iocoder.yudao.module.system.core.ErpOperationLog;
import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
import cn.iocoder.yudao.module.system.dal.dataobject.erp.customermanage.CustomerManageDO;
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
import cn.iocoder.yudao.module.system.enums.common.SexEnum;
import cn.iocoder.yudao.module.system.framework.CommonConstant;
import cn.iocoder.yudao.module.system.service.dept.DeptService;
import cn.iocoder.yudao.module.system.service.erp.customermanage.CustomerManageService;
import cn.iocoder.yudao.module.system.service.erp.operatelog.ErpOperateLogService;
import cn.iocoder.yudao.module.system.service.user.AdminUserService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.Valid;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
import static cn.iocoder.yudao.framework.common.util.http.HttpUtils.getClientPublicIP;
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.USER_NOT_EXISTS;

@Tag(name = "管理后台 - 用户")
@RestController
@RequestMapping("/erp/user")
public class ErpUserController {

    @Resource
    private AdminUserService userService;
    @Resource
    private CustomerManageService customerManageService;
    @Resource
    private ErpOperateLogService erpOperateLogService;


    @PostMapping("/create")
    @Operation(summary = "新增用户")
    @ErpOperationLog(module = "用户管理",description = "新增用户")
//    @PreAuthorize("@ss.hasPermission('system:erp-user:create')")
    public CommonResult<Long> createUser(@RequestBody UserSaveReqVO reqVO) throws NoSuchMethodException {
        Long id = userService.createErpUser(reqVO);
        AdminUserDO user = BeanUtils.toBean(reqVO, AdminUserDO.class);
        String content=" "+Arrays.stream(user.getClass().getDeclaredFields()).filter(field->ObjectUtil.isNotNull(field.getAnnotation(ErpOperationField.class))
        ).map(field -> {field.setAccessible(true);try{
            return field.getAnnotation(ErpOperationField.class).name() + ":" + field.get(user);
        } catch (IllegalAccessException e) {throw new RuntimeException(e);}
        }).collect(Collectors.joining(","));
        erpOperateLogService.createOperateLog(SecurityFrameworkUtils.getLoginUserId(),content,getClass().getDeclaredMethod("createUser",UserSaveReqVO.class));
        return success(id);
    }

    @PutMapping("update")
    @Operation(summary = "修改用户")
//    @PreAuthorize("@ss.hasPermission('system:erp-user:update')")
    @ErpOperationLog(module = "用户管理",description = "修改用户")
    public CommonResult<Boolean> updateUser( @RequestBody UserSaveReqVO reqVO) throws NoSuchMethodException {
        AdminUserDO oldUser = userService.getUser(reqVO.getId());
        userService.updateErpUser(reqVO);
        AdminUserDO newUser = userService.getUser(reqVO.getId());
        String oldContent=" 原来数据 "+Arrays.stream(oldUser.getClass().getDeclaredFields()).filter(field->ObjectUtil.isNotNull(field.getAnnotation(ErpOperationField.class))
        ).map(field -> {field.setAccessible(true);try{
            return field.getAnnotation(ErpOperationField.class).name() + ":" + field.get(oldUser);
        } catch (IllegalAccessException e) {throw new RuntimeException(e);}
        }).collect(Collectors.joining(","));
        String newContent=";修改完数据 "+Arrays.stream(newUser.getClass().getDeclaredFields()).filter(field->ObjectUtil.isNotNull(field.getAnnotation(ErpOperationField.class))
        ).map(field -> {field.setAccessible(true);try{
            return field.getAnnotation(ErpOperationField.class).name() + ":" + field.get(newUser);
        } catch (IllegalAccessException e) {throw new RuntimeException(e);}
        }).collect(Collectors.joining(","));
        String content=oldContent.concat(newContent);
        erpOperateLogService.createOperateLog(SecurityFrameworkUtils.getLoginUserId(),content,getClass().getDeclaredMethod("updateUser",UserSaveReqVO.class));
        return success(true);
    }

    @DeleteMapping("/delete")
    @Operation(summary = "删除用户")
    @ErpOperationLog(module = "用户管理",description = "删除用户")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
//    @PreAuthorize("@ss.hasPermission('system:erp-user:delete')")
    public CommonResult<Boolean> deleteUser(@RequestParam("id") Long id) throws NoSuchMethodException {
        AdminUserDO oldUser = userService.getUser(id);
        userService.deleteUser(id);
        String content= oldUser.getNickname();
        erpOperateLogService.createOperateLog(SecurityFrameworkUtils.getLoginUserId(),content,getClass().getDeclaredMethod("updateUser",UserSaveReqVO.class));
        return success(true);
    }

    @PostMapping("/batch-delete")
    @Operation(summary = "批量删除用户")
    @ErpOperationLog(module = "用户管理",description = "批量删除用户")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
//    @PreAuthorize("@ss.hasPermission('system:erp-user:delete')")
    public CommonResult<Boolean> batchDeleteUser(@RequestBody List<Long>ids) throws NoSuchMethodException {
        List<String> names = new ArrayList<>();
        for(Long id:ids){
        AdminUserDO user = userService.getUser(id);
        if(ObjectUtil.isNull(user)){
            break;
        }
        userService.deleteUser(id);
        names.add(user.getNickname());
        }
        String content= String.join(",",names);
        erpOperateLogService.createOperateLog(SecurityFrameworkUtils.getLoginUserId(),content,getClass().getDeclaredMethod("updateUser",UserSaveReqVO.class));
        return success(true);
    }

    @PutMapping("/update-password")
    @Operation(summary = "重置用户密码")
    @ErpOperationLog(module = "用户管理")
//    @PreAuthorize("@ss.hasPermission('system:erp-user:update-password')")
    public CommonResult<Boolean> updateUserPassword(@RequestBody UserUpdatePasswordReqVO reqVO) throws NoSuchMethodException {
        AdminUserDO user = userService.getUser(reqVO.getId());
        userService.updateUserPassword(reqVO.getId(), reqVO.getPassword());
        String content= user.getNickname()+"重置密码 ,原密码:"+user.getPassword()+";新密码:"+user.getPasswordPlaintext();
        erpOperateLogService.createOperateLog(SecurityFrameworkUtils.getLoginUserId(),content,getClass().getDeclaredMethod("updateUser",UserSaveReqVO.class));
        return success(true);
    }


    @GetMapping("/page")
    @Operation(summary = "获得用户分页列表")
    @PreAuthorize("@ss.hasPermission('system:erp-user:query')")
    public CommonResult<PageResult<AdminUserDO>> getUserPage( UserPageReqVO pageReqVO) {
        // 获得用户分页列表
        PageResult<AdminUserDO> pageResult = userService.getErpUserPage(pageReqVO);
        if (CollUtil.isEmpty(pageResult.getList())) {
            return success(new PageResult<>(pageResult.getTotal()));
        }
        return success(new PageResult<>(pageResult.getList(),pageResult.getTotal()));
    }

    @GetMapping("/get")
    @Operation(summary = "获得用户详情")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    @PreAuthorize("@ss.hasPermission('system:erp-user:query')")
    public CommonResult<AdminUserDO> getUser(@RequestParam("id") Long id) {
        AdminUserDO user = userService.getUser(id);
        return success(user);
    }



    @PostMapping("/customer-page")
    @Operation(summary = "获得管理员对应的客户分页列表")
    @PreAuthorize("@ss.hasPermission('system:erp-customer-user:query')")
    public CommonResult<PageResult<AdminUserDO>> getCustomerPage(@RequestBody UserPageReqVO pageReqVO) {
        Long loginUserId= SecurityFrameworkUtils.getLoginUserId();
        AdminUserDO user = userService.getUser(loginUserId);
        if(!ObjectUtil.equal(loginUserId,1L)&&!ObjectUtil.equal(user.getRoleCode(), CommonConstant.ERP_SUPER_ADMIN)){
                throw exception(new ErrorCode(500,"无操作权限"));
        }
        PageResult<AdminUserDO>pageResult=new PageResult<>();
        Long adminId=pageReqVO.getAdminId();
        if(ObjectUtil.isNull(adminId)){throw exception(new ErrorCode(500,"普通管理员id不能为空"));}
        List<Long>customerIds=customerManageService.getCustomerIds(adminId);
        if(customerIds.isEmpty()){return success(pageResult);}
        pageReqVO.setCustomerIds(customerIds);
        pageResult=userService.getErpUserPage(pageReqVO);
        return success(new PageResult<>(pageResult.getList(), pageResult.getTotal()));
    }

    @PostMapping("/customer-not-opt-page")
    @Operation(summary = "获取未分配的客户分页列表")
    @PreAuthorize("@ss.hasPermission('system:erp-customer-user:query')")
    public CommonResult<PageResult<AdminUserDO>> getCustomerOptionalPage(@RequestBody UserPageReqVO pageReqVO) {
        Long loginUserId= SecurityFrameworkUtils.getLoginUserId();
        AdminUserDO user = userService.getUser(loginUserId);
        if(!ObjectUtil.equal(loginUserId,1L)&&!ObjectUtil.equal(user.getRoleCode(), CommonConstant.ERP_SUPER_ADMIN)){
            throw exception(new ErrorCode(500,"无操作权限"));
        }
        pageReqVO.setFindNotOpt(true);
        PageResult<AdminUserDO>pageResult=userService.getErpUserPage(pageReqVO);
        return success(new PageResult<>(pageResult.getList(), pageResult.getTotal()));
    }
    @PostMapping("/customer-add")
    @Operation(summary = "获得管理员对应的客户分页列表")
    @ErpOperationLog(module = "客户信息",description = "绑定")
//    @PreAuthorize("@ss.hasPermission('system:erp-customer-user:add')")
    public CommonResult<Boolean> customerAdd(@RequestBody ErpUserReqVO reqVO) throws NoSuchMethodException {
        Long adminId = reqVO.getAdminId();
        if(ObjectUtil.isNull(adminId)){
            throw exception(new ErrorCode(500,"管理员ID不能为空"));
        }
        AdminUserDO admin = userService.getUser(adminId);
        if(ObjectUtil.isNull(admin)||!ObjectUtil.equal(admin.getRoleCode(),CommonConstant.ERP_ADMIN)){
            throw exception(new ErrorCode(500,"管理员ID错误"));
        }
        Long customerId = reqVO.getCustomerId();
        if(ObjectUtil.isNull(customerId)){
            throw exception(new ErrorCode(500,"客户ID不能为空"));
        }
        AdminUserDO customer = userService.getUser(customerId);
        if(ObjectUtil.isNull(customer)||!ObjectUtil.equal(customer.getRoleCode(),CommonConstant.ERP_CUSTOMER)){
            throw exception(new ErrorCode(500,"客户ID错误"));
        }
        CustomerManageDO customerManageDO = customerManageService.byCustomerId(customerId);
        if(ObjectUtil.isNull(customerManageDO)){
            throw exception(new ErrorCode(500,"已经被分配到管理员下"));
        }
        CustomerManageSaveReqVO customerManage = new CustomerManageSaveReqVO();
        customerManage.setCustomerId(customerId);
        customerManage.setAdminId(adminId);
        customerManageService.createCustomerManage(customerManage);

        String content= userService.getUser(adminId).getNickname()+"管理员绑定"+userService.getUser(customerId).getNickname()+"客户.";
        erpOperateLogService.createOperateLog(SecurityFrameworkUtils.getLoginUserId(),content,getClass().getDeclaredMethod("customerAdd",ErpUserReqVO.class));
        return success(true);
    }

    @PostMapping("/customer-delete")
    @Operation(summary = "删除管理员下的客户")
    @ErpOperationLog(module = "客户信息")
//    @PreAuthorize("@ss.hasPermission('system:erp-customer-user:delete')")
    public CommonResult<Boolean> customerDelete(@RequestBody ErpUserReqVO reqVO) throws NoSuchMethodException {
        Long adminId = reqVO.getAdminId();
        if(ObjectUtil.isNull(adminId)){
            throw exception(new ErrorCode(500,"管理员ID不能为空"));
        }
        Long customerId = reqVO.getCustomerId();
        if(ObjectUtil.isNull(customerId)){
            throw exception(new ErrorCode(500,"客户ID不能为空"));
        }
        customerManageService.deleteAdminIdCustomerId(customerId,adminId);
        String content= "解除"+userService.getUser(adminId).getNickname()+"管理员下的"+userService.getUser(customerId).getNickname()+"客户.";
        erpOperateLogService.createOperateLog(SecurityFrameworkUtils.getLoginUserId(),content,getClass().getDeclaredMethod("customerDelete",ErpUserReqVO.class));
        return success(true);
    }

}
